/**
 * @项目名称: lession01
 * @文件名称: Datatype_Key.java
 * @Date: 2016年9月21日
 * @Copyright: 2016 www.yunhe.cn Inc. All rights reserved.
 * 注意：本内容仅限于云和数据公司内部传阅，禁止外泄以及用于其他的商业目的
*/
package com.cn.yunhe.redis.study;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

/**
 * 
 * JEDIS常用的SortedSet数据类型的操作方法
 * 
 * @author ZSL
 *
 */
public class Datatype_SortedSet {

	/**
	 * 日志工具
	 */
	Logger logger = Logger.getLogger(Datatype_SortedSet.class);
	
	/**
	 * 测试操作
	 * 
	 * 以下是多数相对常用的KEY操作
	 * 
	 * 其他未涉及到的自己可以扩展查询命令练习下
	 * 
	 * 工作生产环境中根据具体业务，需要用到了再去查资料调用某个命令方法即可。
	 * 
	 * 生产数据库数据至少在百万级别以上，REDIS存储的效率提升很明显
	 * 
	 */
	@Test
	public void operator(){
		
		Jedis client = new Jedis("127.0.0.1",6379);
		client.auth("123456");

        client.flushDB();
        Map<String,Double> map = new HashMap<>();
        map.put("zhangsan",88.2);
        map.put("lisi",95.0);
        map.put("wangwu",68.0);
        
        logger.debug(client.zadd("zset", 3,"key1"));
        logger.debug(client.zadd("zset",map));
        
        logger.debug("zset中的所有元素："+client.zrange("zset", 0, -1));
        logger.debug("zset中的所有元素："+client.zrangeWithScores("zset", 0, -1));
        logger.debug("zset中的所有元素："+client.zrangeByScore("zset", 0,100));
        logger.debug("zset中的所有元素："+client.zrangeByScoreWithScores("zset", 0,100));
        
        //按成绩分值倒叙排列，最大分值为80分，最小分值为0分。
        Set<Tuple> ss  = client.zrevrangeByScoreWithScores("zset", 80,0);
        for(Tuple item:ss){
        	logger.debug("#元素："+item.getElement()+",成绩："+item.getScore());
        }
        
        
        logger.debug("zset中key2的分值："+client.zscore("zset", "key2"));
        logger.debug("zset中key2的排名："+client.zrank("zset", "key2"));
        logger.debug("删除zset中的元素key3："+client.zrem("zset", "key3"));
        logger.debug("zset中的所有元素："+client.zrange("zset", 0, -1));
        logger.debug("zset中元素的个数："+client.zcard("zset"));
        logger.debug("zset中分值在1-4之间的元素的个数："+client.zcount("zset", 1, 4));
        logger.debug("key2的分值加上5："+client.zincrby("zset", 5, "key2"));
        logger.debug("key3的分值加上4："+client.zincrby("zset", 4, "key3"));
        logger.debug("zset中的所有元素："+client.zrange("zset", 0, -1));
        
        
        //2个集合元素并集，元素一样的成绩分值相加
        Map<String,Double> csMap1 = new HashMap<>();
        csMap1.put("zhangsan",88.2);
        csMap1.put("lisi",95.0);
        csMap1.put("wangwu",68.0);
        client.zadd("csSet1", csMap1);
        
        Map<String,Double> csMap2 = new HashMap<>();
        csMap2.put("zhaolong",88.2);
        csMap2.put("lisi",95.0);
        csMap2.put("wangwu",68.0);
        client.zadd("csSet2", csMap2);

        //2个集合并集存储到total集合中
        client.zunionstore("total", "csSet1","csSet2");
        //打印输出结果集合的元素信息
        for(Tuple item:client.zrangeWithScores("total", 0, -1)){
        	logger.debug("#元素："+item.getElement()+",成绩："+item.getScore());
        }

		client.close();
	}

	/**
	 * 在线游戏积分排行榜例子
	 * 游戏名：奔跑吧，云和！
	 * 1、 用随机的UUID模拟若干个游戏玩家
	 * 2、为这些游戏玩家模拟得分
	 * 3、把玩家的编号和得分信息塞入到REDIS缓存的SORTEDSET中
	 * 4、按照得分从高到低，输出打印玩家的编号和得分列表
	 * 5、打印输出前5名玩家信息
	 * 6、打印输出积分在1000~2000分内的玩家信息
	 *
	 */
	@Test
	public void testGameRank(){
		
	}
	
	
	/**
	 * 当日积分、周积分排行榜例子
	 * 一般排行榜都是有实效性的，比如“用户积分榜”。如果没有实效性一直按照总榜来排，可能榜首总是几个老用户，对于新用户来说，那真是太令人沮丧了。
	 * 1、首先，来个“今日积分榜”吧，排序规则是今日用户新增积分从多到少
	 * 2、利用并集实现多天的积分总和，实现“上周积分榜”
	 * “月度榜”、“季度榜”、“年度榜”等等就以此类推。
	 *
	 */
	@Test
	public void testDayWeekRank(){
		Jedis client = new Jedis("127.0.0.1",6379);
		client.auth("123456");
		
		client.zincrby("rank_20160923", 1.0, "u1001");
		client.zincrby("rank_20160923", 2.0, "u1002");
		client.zincrby("rank_20160923", 3.0, "u1003");
		
		//TODO:上周
		
		
		
		client.close();
	}
	
	
}
